<%#
    File name : mtk_wifi_map_bssinfo.htm
    This file is used in WebUI based on LuCI
    to display the feature of EasyMesh Configurations
    named as Front-haul status per BSS.
%>
<%+header%>

<script src="/luci-static/resources/monCon.js"></script>

<h2><a>EasyMesh Front-haul Status per BSS</a></h2>
<div class="alert-message" id="get_bssinfo_msg_div">
    <img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" />
    <big><strong>Retrieving EasyMesh Front-haul Status per BSS Information!</strong></big>
</div>
<div class="alert-message error" style="display:none">
    <span><strong id="bssinfo_err_msg_div"></strong></span>
</div>
<div id="bssinfo_display"></div>

<script type="text/javascript">

    var max_cellspan = 2;

    function set_max_cellspan(o)
    {
        for(var k in o){
            var v = o[k];
            if (v instanceof Array){
                max_cellspan++;
                for(var a_idx=0; a_idx < v.length; a_idx++){
                    if(((typeof v[a_idx]) == "object") && v[a_idx] != null){
                        set_max_cellspan(v[a_idx]);
                    }
                    else{
                        console.log("set_max_cellspan: Incorrect Topology: Array element is not an object!",v[a_idx]);
                    }
                }
            }
            else if(((typeof v) == "object") && v != null){
                set_max_cellspan(v);
            }
        }
    }

    function set_rowspan(o)
    {
        var rowspan = 0;
        for(var k in o){
            var v = o[k];
            if (v instanceof Array){
                for(var a_idx=0; a_idx < v.length; a_idx++){
                    if(((typeof v[a_idx]) == "object") && v[a_idx] != null){
                        rowspan = rowspan + set_rowspan(v[a_idx]);
                    }
                    else{
                        console.log("set_rowspan: Incorrect Topology: Array element is not an object!",v[a_idx]);
                    }
                }
            }
            else if(((typeof v) == "object") && v != null){
                rowspan = rowspan + set_rowspan(v);
            }
            else{
                rowspan++;
            }
        }
        return rowspan;
    }

    function obj_loop(table_id, row, o)
    {
        var cell;
        for(var k in o){
            var v = o[k];
            if (v instanceof Array){
                arr_loop(table_id, k, v);
            }
            else if(((typeof v) == "object") && v != null){
                obj_loop(table_id, row, v);
            }
            else{
                if(row == null){
                    row = table_id.insertRow(-1);
                }
            cell = row.insertCell(-1);
            cell.innerHTML = k;
            cell = row.insertCell(-1);
            cell.colSpan = max_cellspan - row.cells.length + 1;
            if(k == "Security"){
                cell.innerHTML = get_auth_mode_str(v);
            }
            else if(k == "wireless mode"){
                cell.innerHTML = get_wireless_mode_str(v);
            }
            else if(k == "Encryption"){
                cell.innerHTML = get_encryp_mode_str(v);
            }
            else{
                cell.innerHTML = v;
            }
            row = null;
            }
        }
    }

    function arr_loop(table_id, k, a)
    {
        var row, cell;
        for(var a_idx=0; a_idx < a.length; a_idx++){
            var v = a[a_idx];
            if(((typeof v) == "object") && v != null){
                row = table_id.insertRow(-1);
                cell = row.insertCell(-1);
                cell.rowSpan = set_rowspan(v);
                cell.style.verticalAlign  = "middle";
                cell.innerHTML = "<strong>" + k + ' - ' + (a_idx + 1) + "</strong>";
                obj_loop(table_id, row, v);
            }
            else{
                console.log("Incorrect Topology: Array element is not an object!",a);
            }
        }
    }

    function get_auth_mode_str(authModeCode)
    {
        switch(authModeCode){
            case "0001":
                return "Open";
            case "0002":
                return "WPA - Personal";
            case "0004":
                return "Shared";
            case "0008":
                return "WPA - Enterprise";
            case "0010":
                return "WPA2 - Enterprise";
            case "0020":
                return "WPA2 - Personal";
            case "0040":
                return "WPA3 - SAE Only";
            case "0060":
                return "WPA3 - Transition Mode";
            case "00A0":
                return "DPP + WPA2 - Personal";
            case "00C0":
                return "DPP + WPA3 - SAE";
            case "00E0":
                return "DPP + WPA3 - Transition Mode";
            default:
                return "Unknown Security Code: " + authModeCode;
        }
    }

    function get_wireless_mode_str(wirelessMode)
    {
        switch(wirelessMode){
            case "0":
                return "CCK";
            case "1":
                return "OFDM";
            case "2":
                return "HTMIX";
            case "3":
                return "HTGREENFIELD";
            case "4":
                return "VHT";
            default:
                return "Unknown Wireless Mode: " + wirelessMode;
        }
    }

    function get_encryp_mode_str(encrypMode)
    {
        switch(encrypMode){
            case "0001":
                return "OPEN";
            case "0002":
                return "WPAPSK";
            case "0004":
                return "Shared";
            case "0008":
                return "WPA";
            case "0010":
                return "WPA2";
            case "0020":
                return "WPA2PSK";
            case "0080":
                return "WPANONE";
            default:
                return "Unknown Encryption Mode: " + encrypMode;
        }
    }

    function draw_bssinfo_table(devRole, obj_1905, alMac)
    {
        if(!obj_1905.hasOwnProperty('Radio Info')){
            console.log("Topology has no Radio Info Property!",obj_1905);
            document.getElementById("get_bssinfo_msg_div").style.display = "none";
            document.getElementById("bssinfo_err_msg_div").innerHTML = "Incorrect TopologyInfo: topology information has no Radio Info Property!!<br /> UI will retry in a short while.";
            document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
            return;
        }
        var devRoleStr = (devRole == 1) ? "Controller" : "Agent";
        var bssInfoDb = {};
        bssInfoDb["Radio Info"] = obj_1905['Radio Info'];
        var bssinfo_tbl = document.createElement("TABLE");
        bssinfo_tbl.setAttribute("class", "cbi-section-table");
        var dev1905fset = document.createElement("FIELDSET");
        dev1905fset.setAttribute("class", "cbi-section");
        var dev1905legend = document.createElement("LEGEND");
        var dev1905a = document.createElement("A");
        var dev1905text = document.createTextNode("Radio Info of "+ devRoleStr +" with AL-MAC " + alMac);
        dev1905a.setAttribute("href", "#");
        dev1905a.appendChild(dev1905text);
        dev1905legend.appendChild(dev1905a);
        dev1905fset.appendChild(dev1905legend);
        document.getElementById("bssinfo_display").appendChild(dev1905fset);

        set_max_cellspan(bssInfoDb);
        obj_loop(bssinfo_tbl, null, bssInfoDb);

        document.getElementById("bssinfo_display").appendChild(bssinfo_tbl);
        document.getElementById("bssinfo_display").style.display = "";
        document.getElementById("get_bssinfo_msg_div").style.display = "none";
    }

    function find_own_topo_info(devRole, jsTopoInfo, alMac)
    {
        var tree_info = [];
        var topoInfoArr = jsTopoInfo['topology information'];
        if(!(topoInfoArr instanceof Array)){
            console.log("Incorrect TopologyInfo: Value of topology information is not an Array!");
            document.getElementById("get_bssinfo_msg_div").style.display = "none";
            document.getElementById("bssinfo_err_msg_div").innerHTML = "Incorrect TopologyInfo: Value of topology information key is not an Array!<br /> UI will retry in a short while.";
            document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
            window.setTimeout(get_bssinfo, 60000);
            return;
        }
        for(var idx_1905=0; idx_1905 < topoInfoArr.length; idx_1905++){
            var obj_1905 = topoInfoArr[idx_1905];
            if (obj_1905.hasOwnProperty('AL MAC') && (obj_1905['AL MAC'].toUpperCase() == alMac.toUpperCase())){
                draw_bssinfo_table(devRole, obj_1905, alMac);
                window.setTimeout(get_bssinfo, 60000);
                return;
            }
        }
        console.log(alMac," AL-MAC NOT FOUND in Topology! Topology: ",jsTopoInfo);
        document.getElementById("get_bssinfo_msg_div").style.display = "none";
        document.getElementById("bssinfo_err_msg_div").innerHTML = alMac + " AL-MAC is not found in topology information!<br /> UI will retry in a short while.";
        document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
        window.setTimeout(get_bssinfo, 60000);
    }

    function get_al_mac(devRole, jsTopoInfo)
    {
        XHR.get('<%=luci.dispatcher.build_url("admin", "mtk", "multi_ap", "get_al_mac")%>' + '/' + devRole, null, 
            function(x)
            {
                console.log(x);
                try{
                    var r = JSON.parse(x.response);
                    var mac_reg_exp = /[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}/;
                    if (r['status'] == "SUCCESS" && mac_reg_exp.test(r['al_mac'])) {
                        find_own_topo_info(devRole, jsTopoInfo, r['al_mac']);
                    }
                    else{
                        console.log("Incorrect AL-MAC received!",r['status'],r['al_mac']);
                        document.getElementById("get_bssinfo_msg_div").style.display = "none";
                        document.getElementById("bssinfo_err_msg_div").innerHTML = "Incorrect AL-MAC received!<br />Status: " + r.status + "<br />AL-MAC: " + r['al_mac'] +"<br /> UI will retry in a short while.";
                        document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
                        window.setTimeout(get_bssinfo, 60000);
                    }
                }
                catch(e){
                    console.log("Incorrect response received for get AL-MAC request!",e.name,e.message);
                    document.getElementById("get_bssinfo_msg_div").style.display = "none";
                    document.getElementById("bssinfo_err_msg_div").innerHTML = "Incorrect response received for get AL-MAC request!<br />" + e.name + " " + e.message + "<br /> UI will retry in a short while.";
                    document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
                    window.setTimeout(get_bssinfo, 60000);
                }
            }
        );
    }

    function get_run_time_topology(devRole)
    {
        XHR.get('<%=luci.dispatcher.build_url("admin", "mtk", "multi_ap", "get_runtime_topology")%>', null, 
            function(x)
            {
                try{
                    var r = JSON.parse(x.response);
                    if(r.status == "SUCCESS"){
                        var jsTopoInfo = JSON.parse(r['luaTopologyInfo']);
                        get_al_mac(devRole, jsTopoInfo);
                    }
                    else{
                        console.log("Failed to get Topology Info!\nStatus: ",r.status);
                        document.getElementById("get_bssinfo_msg_div").style.display = "none";
                        document.getElementById("bssinfo_err_msg_div").innerHTML = "Failed to get Topology Info!<br />Status: " + r.status + "<br /> UI will retry in a short while.";
                        document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
                        window.setTimeout(get_bssinfo, 60000);
                    }
                }
                catch(e){
                    console.log("Incorrect response! Failed to get Topology Info!",e.name,e.message);
                    document.getElementById("get_bssinfo_msg_div").style.display = "none";
                    document.getElementById("bssinfo_err_msg_div").innerHTML = "Incorrect response! Failed to get Topology Info!<br />" + e.name + " " + e.message + "<br /> UI will retry in a short while.";
                    document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
                    window.setTimeout(get_bssinfo, 60000);
                }
            }
        );
    }

    function get_device_role()
    {
        XHR.get('<%=luci.dispatcher.build_url("admin", "mtk", "multi_ap", "get_device_role")%>', null, 
            function(x)
            {
                console.log(x);
                try{
                    var devRoleObj = JSON.parse(x.response);
                    var devRole = parseInt(devRoleObj.mapDevRole);
                    if(devRole != 2 && devRole != 1){
                        console.log("Device Role is neither Controller nor Agent!");
                        document.getElementById("get_bssinfo_msg_div").style.display = "none";
                        document.getElementById("bssinfo_err_msg_div").innerHTML = "Device Role is neither Controller nor Agent! <br /> UI will retry in a short while.";
                        document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
                        window.setTimeout(get_bssinfo, 60000);
                        return;
                    }
                    get_run_time_topology(devRole);
                }
                catch(e){
                    console.log("Incorrect response received for get device role request!",e.name,e.message);
                    document.getElementById("get_bssinfo_msg_div").style.display = "none";
                    document.getElementById("bssinfo_err_msg_div").innerHTML = "Incorrect response received for get device role request!<br />"+" "+ e.name + " " + e.message + "<br /> UI will retry in a short while.";
                    document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "";
                    window.setTimeout(get_bssinfo, 60000);
                }
            }
        );
    }

    function get_bssinfo()
    {
        document.getElementById("bssinfo_err_msg_div").innerHTML = "";
        document.getElementById("bssinfo_err_msg_div").parentNode.parentNode.style.display = "none";
        document.getElementById("bssinfo_display").style.display = "none";
        document.getElementById("bssinfo_display").innerHTML = "";
        document.getElementById("get_bssinfo_msg_div").style.display = "";
        get_device_role();
    }

    window.onload = function(){
        MonCon.ping();
        window.setTimeout(get_bssinfo, 1);
    }

</script>
<%+footer%>
